#Needed additional modules: python-libtorrent & pyunpack (patool as well)
import libtorrent as lt
import time,os,re
from pyunpack import Archive
from Globals import *
from threading import *

class torrent():
	'''
	Deze plugin laat het toe om de mediacontroller torrents te laten downloaden en deze dan af te spelen in een playlist. 
	COMMAND: torrent info_hash
	''' 
	magnet = None
	storageDir = "/home/tom/music"
	deleteArchives = True
	portUno = 6881
	portDouzo = 6891
	ses = lt.session()
	ses.listen_on(portUno, portDouzo)
	handlers = ([])
	magnets = ([])
	def __init__(self,c):
		self.callback = c

	def addMagnet(self,m):
		if re.match('([A-Fa-f\d]+)',m):
			params = { 'save_path': self.storageDir + "/" + m,'storage_mode': lt.storage_mode_t(2),'paused': False,'auto_managed': True,'duplicate_is_error': True}
	 		self.handlers.append(lt.add_magnet_uri(self.ses, "magnet:?xt=urn:btih:" + m + "&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80" ,params))
	 	else:
	 		print "No match!"
	 		return None

	#Looks if someone called for torrent {magnet}
	def commando(self,args):
		magnet = re.match("^torrent ([A-Fa-f\d]{40})\n$",args['data'],re.IGNORECASE)
		if magnet is not None and magnet.group(1) not in self.magnets:
			print "Received a torrent! %s " % (magnet.group(1))
			self.magnets.append(magnet.group(1))
			self.addMagnet(magnet.group(1))
		elif re.match("^torrent (.*)$",args['data'],re.IGNORECASE) and magnet.group(1) not in self.magnets:
			args['clientsocket'].send("[TORRENT] Not a valid info_hash")
		else:
			pass

	def torrentStatus(self):
	 	for h in self.handlers:
	 		if h.has_metadata():
	 			s = h.status()
				state_str = ['queued', 'checking', 'downloading metadata', 'downloading', 'finished', 'seeding', 'allocating']
		       		print '%.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d) %s' % (s.progress * 100, s.download_rate / 1000, s.upload_rate / 1000, s.num_peers, state_str[s.state])
				if h.is_seed():				#Package has been downloaded
					h.pause()				#Put package on pause
					self.handlers.remove(h)		#Remove handle from handlers
					self.downloadComplete(h)		#Call downloadcomplete for this package
					self.ses.remove_torrent(h)	#Remove handle from torrentsession

	def downloadComplete(self,h):
		print "Download done!"
		for tfile in h.get_torrent_info().files():
			if re.match("^(.*)\.(rar|zip|7z)$",tfile.path,re.IGNORECASE):
				try:
					Archive(h.save_path() + "/" + tfile.path).extractall(h.save_path())
				except ValueError as e:
					print "Error while trying to extract! Have you installed patool as well (if not, only zip files can be unzipped"
				 	return -1
				if deleteArchives:
					os.remove(h.save_path() + "/" + tfile.path)
		p = open(h.save_path() + "/playlist.mc", "w")
		for root, subFolders, files in os.walk(h.save_path()):	
			for file_name in files:
				if re.match('^(.*)\.(mp3|flv|ogg|wav|mp4)',file_name,re.IGNORECASE):
					p.write("%s/%s\n" % (root,file_name))
		p.close() 	
		self.callback.playPlaylist(h.save_path() + "/playlist.mc")
	 	#Call mediacontroller folder adder

def run():
	global hook, mainl
	mainl = torrent(hook.main)
	hook.registerHook('unhandledCommand_before', mainl.commando)
	Timer(5,whileloop).start()

def whileloop():
	mainl.torrentStatus()
	Timer(5,whileloop).start()

